package com.hsmpay.mobile.action.trans;

import com.hsmpay.common.pojo.BasePojo;
import com.hsmpay.common.pojo.qian4.Qian4SendLog;
import com.hsmpay.common.pojo.user.User;
import com.hsmpay.common.util.DateConvertUtil;
import com.hsmpay.common.util.NumberUtil;
import com.hsmpay.common.util.URLDecoderTools;
import com.hsmpay.common.util.system.Constant;
import com.hsmpay.mobile.action.account.fc.PurchaseBaseAction;
import com.hsmpay.mobile.pojo.other.Settings;
import com.hsmpay.mobile.pojo.terminal.Tchannel;
import com.hsmpay.mobile.pojo.trans.*;
import com.hsmpay.mobile.pojo.trans.cardcer.CardCer;
import com.hsmpay.mobile.pojo.user.UserTransLimit;
import com.hsmpay.mobile.service.other.SettingsService;
import com.hsmpay.mobile.service.terminal.TchannelService;
import com.hsmpay.mobile.service.trans.SSBindCardsService;
import com.hsmpay.mobile.service.trans.TransOrderService;
import com.hsmpay.mobile.service.trans.TransRefuseCardService;
import com.hsmpay.mobile.service.trans.cardcer.CardCerService;
import com.hsmpay.mobile.service.user.UserTransLimitService;
import com.hsmpay.mobile.util.ImgFileUpload;
import com.hsmpay.mobile.util.icc.ME30DataDecode;
import com.hsmpay.qian4.pojo.PurchaseResult;
import com.hsmpay.qian4.pojo.send.ICCardParam;
import com.hsmpay.utils.Des3;
import com.hsmpay.utils.TimeUtils;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by zhy on 16/4/13.
 */
@Controller("settleSecondsAction")
@Scope("prototype")
public class SettleSecondsAction extends PurchaseBaseAction{

    private static Logger log = Logger.getLogger(SettleSecondsAction.class);

    @Resource(name = "settingsService")
    protected SettingsService<Settings, Long> settingsService;
    @Resource(name = "transOrderService")
    private TransOrderService<TransOrder, Long> transOrderService;
    @Resource(name = "cardCerService")
    private CardCerService<CardCer, Long> cardCerService;
    @Resource(name = "transRefuseCardService")
    protected TransRefuseCardService<BasePojo, Long> transRefuseCardService;//拒绝卡号交易
    @Resource(name = "tchannelService")
    public TchannelService<Tchannel, Long> tchannelService;
    @Resource(name = "userTransLimitService")
    private UserTransLimitService<BasePojo, Long> userTransLimitService;
    @Resource(name = "ssBindCardsService")
    private SSBindCardsService<SSBindCards, Long> ssBindCardsService; // 秒到业务

    private String transAmt = ""; //交易金额
    private String accountNumber = "";//账号
    /**
     * 上传人工审核 秒到绑定信用卡照片
     * @return
     * @throws Exception
     */
    public String uploadInfoPic() throws Exception {
        String idCard = "";//身份证号
        String cardNumber = "";//卡号
        String orderNum = "";//订单号

        File idAndCardPositive = null;//证件及信用卡正面
        File idAndCardBack = null;//证件及信用卡反面
        File head = null;//手持证件个人照片
        Long cardCerId = null;//认证id

        JSONObject js = JSONObject.fromObject(getRequest().getAttribute(FC_DATA));
        clientType = Integer.parseInt(js.getString("clientType"));
        terminalTypeId = Long.parseLong(js.getString("terminalTypeId"));
        roleId = Long.parseLong(js.getString("roleId"));

        if (js.containsKey("userId"))
            userId = Long.parseLong(js.getString("userId"));
        if (js.containsKey("idCard"))
            idCard = js.getString("idCard");
        if (js.containsKey("cardNumber"))
            cardNumber = js.getString("cardNumber");

         File file = new File(getRealPath("/images") + File.separator + "temp");
         if(!file.exists()){
             file.mkdir();
         }

        if (js.containsKey("idAndCardPositive")) {
            String cardPositiveStr = js.getString("idAndCardPositive");
            String relPath = getRealPath("/images") + File.separator + "temp" + File.separator + DateConvertUtil.dateString(new Date(), "yyyyMMddhhmmssSSS") + ".jpg";
            idAndCardPositive = ImgFileUpload.getPicByBase64Str(relPath, cardPositiveStr);
        }
        if (js.containsKey("idAndCardBack")) {
            String cardBackStr = js.getString("idAndCardBack");
            String relPath = getRealPath("/images") + File.separator + "temp" + File.separator + DateConvertUtil.dateString(new Date(), "yyyyMMddhhmmssSSS") + ".jpg";
            idAndCardBack = ImgFileUpload.getPicByBase64Str(relPath, cardBackStr);

        }
        if (js.containsKey("head")) {
            String headStr = js.getString("head");
            String relPath = getRealPath("/images") + File.separator + "temp" + File.separator + DateConvertUtil.dateString(new Date(), "yyyyMMddhhmmssSSS") + ".jpg";
            head = ImgFileUpload.getPicByBase64Str(relPath, headStr);
        }

        log.debug("clientType = " + clientType);
        log.debug("terminalTypeId = " + terminalTypeId);
        log.debug("roleId = " + roleId);
        log.debug("userId = " + userId);
        log.debug("orderNum = " + orderNum);
        if (null == userId) {
            log.info("秒到上传认证照片时, 传入参数userId为空");
            sendAppErrorMsg("6001", "userId");
            return null;
        }

        if (null == cardNumber){
            log.info("秒到上传认证照片时,传入参数cardNumber为空");
            sendAppErrorMsg("6001","cardNumber");
            return null;
        }
        if (null == idAndCardPositive && null == idAndCardBack && null == head) {
            log.info("秒到上传认证照片时, 传入参数idAndCardPositive为空");
            sendAppErrorMsg("6001", "idAndCardPositive cardBack head");
            return null;
        }

        try {
            //首先生成订单号
            orderNum = getOrderNumByDate(new Date());

            int isCardCer = cardCerService.getSecondsToCardCerStatusByBankCard(cardNumber, userId, 2);//0 代表认证失败 1 认证成功 2 认证处理中  3 未认证
            if (isCardCer == 1) {
                log.warn("卡号已经通过认证，不需要再传认证图片了！");
                sendAppErrorMsg("6120");
                return null;
            }
            if (isCardCer == 2) {
                log.warn("卡号已提交审核，请等待审核结果！");
                sendAppErrorMsg("6121");
                return null;
            }

            CardCer cardCer = new CardCer();
            if (null != cardCerId) {
                cardCer.setId(cardCerId);
                cardCer = cardCerService.searchEntity(cardCer);//根据ID 查询认证信息
                if (null == cardCer) {
                    sendAppErrorMsg("9999");
                }
            }
            cardCer.setBankCard(cardNumber);//卡号
            cardCer.setIdCard(idCard);//身份证号

            String dPIUrl = Constant.getAttribute("SERVER_CARDCER_URL");
            StringBuilder sb = new StringBuilder();
            String dirDateStr = DateConvertUtil.dateString(new Date());
            String baseRPath = ImgFileUpload.mkDirectory(sb.append(getRealPath(dPIUrl)).append(File.separator).append(dirDateStr).toString());
            String fileType = ".jpg";//ImgFileUpload.getFileType(idPositiveFileName);
            String dateStr = "";
            String filePath = "";

            //卡号正面
            if (null != idAndCardPositive) {
                log.debug("秒到认证上传卡号正面");
                dateStr = DateConvertUtil.dateString(new Date(), "hhmmssSSS");
                sb = new StringBuilder();
                filePath = sb.append(baseRPath).append(File.separator).append(dateStr).append(fileType).toString();
                sb = new StringBuilder();
                String cardPositiveUrl = sb.append(dPIUrl).append(dirDateStr).append("/").append(dateStr).append(fileType).toString();
                ImgFileUpload.uploadAndThumd(filePath, idAndCardPositive, 80, 80, terminalTypeId);
                cardCer.setCardPositivePath(cardPositiveUrl);//卡号正面
            }
            //卡号背面
            if (null != idAndCardBack) {
                log.debug("秒到认证上传卡号背面");
                dateStr = DateConvertUtil.dateString(new Date(), "hhmmssSSS");
                sb = new StringBuilder();
                filePath = sb.append(baseRPath).append(File.separator).append(dateStr).append(fileType).toString();
                sb = new StringBuilder();
                String cardBackUrl = sb.append(dPIUrl).append(dirDateStr).append("/").append(dateStr).append(fileType).toString();
                ImgFileUpload.uploadAndThumd(filePath, idAndCardBack, 80, 80, terminalTypeId);
                cardCer.setCardBackPath(cardBackUrl);//卡号背面
            }
            //头像
            if (null != head) {
                log.debug("秒到认证上传卡号头像");
                dateStr = DateConvertUtil.dateString(new Date(), "hhmmssSSS");
                sb = new StringBuilder();
                filePath = sb.append(baseRPath).append(File.separator).append(dateStr).append(fileType).toString();
                sb = new StringBuilder();
                String headUrl = sb.append(dPIUrl).append(dirDateStr).append("/").append(dateStr).append(fileType).toString();
                ImgFileUpload.uploadAndThumd(filePath, head, 80, 80, terminalTypeId);
                cardCer.setHeadPath(headUrl);//头像
            }

            cardCer.setOrderNum(orderNum);
            cardCer.setStatus(3);//未审核
            cardCer.setCreateDate(new Date());
            cardCer.setUserId(userId);
            cardCer.setVerifiType(2);//秒到认证
            cardCerService.insertOrUpdateCardCer(cardCer);

            //根据 卡号  查询 bankCard  认证状态
            Map<String, Object> result = new LinkedHashMap<String, Object>();
            result.put("reqCode", "0000");
            result.put("reqMsg", "上传银行卡认证成功！");
            //result.put("cardCerId", cardCerId);
            result.put("orderNum", orderNum);
            sendAppMsg(result);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (null != idAndCardPositive)
                idAndCardPositive.delete();
            if (null != idAndCardBack)
                idAndCardBack.delete();
            if (null != head)
                head.delete();
        }
        return null;
    }


    /**
     * 获得订单编号
     *
     * @param date
     * @return
     */
    protected String getOrderNumByDate(Date date) {
        StringBuilder sb = new StringBuilder();
        String dt = DateConvertUtil.dateString(date, "yyyyMMddHHmmss");//获得日期字符串
        String userIdStr = NumberUtil.supplyAll(userId, 10);//获得10位userId
        long r = (long) (Math.random() * 10000);//获得四位随机数
        String rStr = NumberUtil.supplyAll(r, 4);
        return sb.append(dt).append(userIdStr).append(rStr).toString();
    }

    /**
     * 秒到线下收款
     * @return
     */
    public String settleSecondsTrans() throws Exception {
        log.debug("--- receivablesToCard() start ---");
        JSONObject js = JSONObject.fromObject(getRequest().getAttribute(FC_DATA));
        terminalTypeId = Long.parseLong(js.getString("terminalTypeId"));
        if (js.containsKey("userId"))
            userId = Long.parseLong(js.getString("userId"));
        if (js.containsKey("transAmt"))
            transAmt = js.getString("transAmt");
        if (js.containsKey("accountNumber"))
            accountNumber = js.getString("accountNumber");
        roleId = Long.parseLong(getJsonString("roleId"));
        //查询用户
        User user = userService.getUserById(userId);
        if (!user.getRoleId().equals(roleId) && user.getRoleId() != 1L && roleId != 4L && roleId != 5L) {//这块添加过滤零费率支付
            log.error("前台传入roleId = " + roleId + " 与当前用户注册roleId = " + user.getRoleId() + "不相符!");
            Map<String, Object> resMap = new HashMap<String, Object>();
            resMap.put("reqCode", "0001");
            resMap.put("reqMsg", "收款交易时,roleId参数异常!");
            sendAppMsg(resMap);
            return null;
        }

        //屏蔽伪卡
        if (transRefuseCardService.isRefuseCard(accountNumber)) {
            sendAppErrorMsg("6073", accountNumber);
            return null;
        }

        //支付  接口
        payOrder(user, roleId);
        return null;
    }


    /**
     * 我要收款
     *
     * @return
     * @throws Exception
     */
    public String payOrder(User user, long roleId) throws Exception {
        functionKey = "SECONDSTO";
        Qian4SendLog send = null;//发送数据
        TransPriorSettle transPriorSettle = null;
        TransOrder transOrder = null;
        Map<String, Object> result = null;
        try {
            if (!checkPIV("SECONDSTO")) {
                log.warn("秒到收款时,银行接口暂停使用!");
                return null;
            }
            user = userService.getUserById(userId);

            if (null != user) {
                User user1 = new User();
                user1.setId(userId);
                user1.setDeleted(0);
                user = userService.searchEntity(user1);
                if (user == null) {
                    Map<String, Object> resMap = new HashMap<String, Object>();
                    log.warn("秒到收款时, 用户Id=" + userId + " 对应的用户不存在!");
                    resMap.put("reqCode", "6004");
                    resMap.put("reqMsg", "用户：" + userId + " 该用户被销户或暂停使用！");
                    resMap.put("channelId", "");
                    sendAppMsg(resMap);
                    return null;
                }
                //获取user对应的刷卡器类型
                Integer machineType = user.getMachineType();
                Object[] resultA = assembleBean(user);
                if (null == resultA) return null;

                send = (Qian4SendLog) resultA[0];
                transOrder = (TransOrder) resultA[1];

                //添加刷卡器类型
                transOrder.setMachineType(machineType);
                int channelId = user.getChannelId().intValue();
                //添加判断:通道是否支持复合卡刷磁条, 是否需要跳转到其他通道
                channelId = whetherChangeChannel(String.valueOf(channelId), send);

                Tchannel tc = tchannelService.searchMobileTchannelByCode(channelId);
                send.setCollectionType(tc.getCode());
                send.setRoleId(roleId);
                //秒到业务单独计算手续费率
                double ssFeeTate = getConfig("SECONDSTO_FEERATE");
                transOrder.setFeeRate(ssFeeTate);
                double fee = calculateFee(user, transOrder.getRoleId(), transOrder.getTransMoney(), transOrder.getFeeRate());

                transOrder.setFeeMoney(fee);
                transOrder.setChargeAmount(transOrder.getTransMoney() - fee);
                //获取数据库中e点的交易限额
                UserTransLimit limit = new UserTransLimit();
                limit.setFunctionKey("EPOINTTRANSLIMIT");
                limit = (UserTransLimit) userTransLimitService.searchEntity(limit);
                long dayCnt = limit.getDayCnt();//得到e点的限额

                switch (channelId) {
                    case PurchaseBaseAction.TC_EPOINT:
                        if (dayCnt > transOrder.getTransMoney()) {
                            send = ds_ECBService.initSend(send, tc);
                            send.setCollectionType(PurchaseBaseAction.TC_ECB);
                        } else {
                            send = ds_ideaioeService.initSend(send, tc);
                        }
                        break;
                    case PurchaseBaseAction.TC_ECB:
                        send = ds_ECBService.initSend(send, tc);
                        break;
                    case PurchaseBaseAction.TC_RuiSheng:
                        send = ds_RuiShengService.initSend(send, tc);
                        if (send.getBatchId() == null) {
                            tc = tchannelService.searchMobileTchannelByCode(PurchaseBaseAction.TC_ECB);
                            send = ds_ECBService.initSend(send, tc);
                            send.setCollectionType(PurchaseBaseAction.TC_ECB);
                        }
                        break;
                    case PurchaseBaseAction.TC_RuiSheng_GT:
                        send = ds_RuiShengGTService.initSend(send, tc);
                        break;
                    case PurchaseBaseAction.TC_POSP:
                        send = ds_pospService.initSend(send, tc, user.getId());
                        break;
                    case PurchaseBaseAction.TC_Uinpay:
                        send = ds_uinpayPayService.initSend(send, tc);
                        break;
                    case PurchaseBaseAction.TC_YinShengBao:
                        send = ds_yinShengBaoService.initSend(send, tc);
                        break;
                    case PurchaseBaseAction.TC_POS:
                        send = ds_posService.initSend(send, tc);
                        break;
                    case PurchaseBaseAction.TC_ZHIFUTONG:
                        send = ds_zhifutongService.initSend(send, tc);
                        break;
                    case PurchaseBaseAction.TC_HANXIN:
                        send = ds_HanXinService.initSend(send, tc);
                        break;
                    case PurchaseBaseAction.TC_ZHONGLAN:
                        send = ds_zhongLanService.initSend(send, tc);
                        break;
                    case PurchaseBaseAction.TC_KAYINKA:
                        send = ds_kaYinKaService.initSend(send, tc);
                        break;
                }

                //下订单
                transPriorSettle = accountManageQ4Service.advanceOrder(transOrder, send, send.getCollectionType());

                //提交给 Q48 接口
                PurchaseResult rs = null;
                switch (send.getCollectionType()) {
                    case PurchaseBaseAction.TC_ECB:
                        rs = ds_ECBService.billPayment(send, tc);
                        break;//ECB
                    case PurchaseBaseAction.TC_RuiSheng:
                        rs = ds_RuiShengService.billPayment(send, tc);
                        break;//瑞晟
                    case PurchaseBaseAction.TC_RuiSheng_GT:
                        rs = ds_RuiShengGTService.billPayment(send, tc);
                        break;//瑞晟
                    case PurchaseBaseAction.TC_POSP:
                        rs = ds_pospService.billPayment(send, tc);//pos
                        break;
                    case PurchaseBaseAction.TC_EPOINT:
                        rs = ds_ideaioeService.billPayment(send, tc);//E点
                        break;
                    case PurchaseBaseAction.TC_Uinpay:
                        rs = ds_uinpayPayService.billPayment(send, tc);//优银
                        break;
                    case PurchaseBaseAction.TC_YinShengBao:
                        rs = ds_yinShengBaoService.billPayment(send, tc);//银生宝
                        break;
                    case PurchaseBaseAction.TC_POS:
                        rs = ds_posService.billPayment(send, tc);//大POS
                        break;
                    case PurchaseBaseAction.TC_ZHIFUTONG:
                        rs = ds_zhifutongService.billPayment(send, tc);
                        break;
                    case PurchaseBaseAction.TC_HANXIN:
                        rs = ds_HanXinService.billPayment(send, tc);
                        break;
                    case PurchaseBaseAction.TC_ZHONGLAN:
                        rs = ds_zhongLanService.billPayment(send, tc);
                        break;
                    case PurchaseBaseAction.TC_KAYINKA:
                        rs = ds_kaYinKaService.billPayment(send, tc);
                        break;
                }

                //解析结果
                result = purchaseResolveResult(send, rs, transOrder, transPriorSettle, user, tc);
                log.debug(result);
                sendAppMsg(result);
            } else {
                log.warn("收款交易时, 用户Id=" + userId + " 对应的用户不存在!");
                sendAppErrorMsg("6012", userId + "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            revocationOrderTimeOut(send, transPriorSettle);
            throw e;
        } finally {
            send = null;
            transPriorSettle = null;
            transOrder = null;
            result = null;
        }
        return null;
    }


    /**
     * 组装数据
     * @param user
     * @return
     * @throws Exception
     */
    public Object[] assembleBean(User user) throws Exception {
        clientType = Integer.parseInt(getJsonString("clientType"));
        terminalTypeId = Long.parseLong(getJsonString("terminalTypeId"));
        roleId = Long.parseLong(getJsonString("roleId"));
        functionKey = getJsonString("functionKey");
        String orderNum = getJsonString("orderNum");
        String merchantOrderId = getJsonString("merchantOrderId").substring(0,17).toString();
        String merchantOrderTime = getJsonString("merchantOrderTime");
        String terminalId = getJsonString("terminalId");
        String transAmt = getJsonString("transAmt");
        String accountNumber = getJsonString("accountNumber");
        String pin = getJsonString("pin");
        String track2Data = getJsonString("track2Data");
        String track3Data = getJsonString("track3Data");
        String dynamicKeyData = getJsonString("dynamicKeyData");
        String merchantSign = getJsonString("merchantSign");
        String senderSign = getJsonString("senderSign");
        String serviceInfo = getJsonString("serviceInfo");
        String terminalInfo = getJsonString("terminalInfo");
        String mac = getJsonString("mac");
        String signaturePath = getJsonString("signaturePath");
        String transTerminalId = getJsonString("transTerminalId");
        functionKey = "SECONDSTO";

        if (5L != roleId) {//不存在
            log.warn("秒到收款时, 传入参数roleId不存在");
            sendAppErrorMsg("6001", "roleId");
            return null;
        }
        String icCardYu = getJsonString("icCardYu");//IC卡 域
        String encryType = getJsonString("encryType");//IC卡 加密类型

        if (null == clientType) {
            log.warn("我要收款时, 传入参数clientType为空");
            sendAppErrorMsg("6001", "clientType");
            return null;
        }

        if (StringUtils.isBlank(orderNum)) {
            log.warn("我要收款时, 传入参数orderNum为空");
            sendAppErrorMsg("6001", "orderNum");
            return null;
        }

        if (null == terminalTypeId) {
            log.warn("我要收款时, 传入参数terminalTypeId为空");
            sendAppErrorMsg("6001", "terminalTypeId");
            return null;
        }

        if (null == userId) {
            log.warn("我要收款时, 传入参数userId为空");
            sendAppErrorMsg("6001", "userId");
            return null;
        }

        if (StringUtils.isBlank(functionKey)) {
            log.warn("我要收款时, 传入参数functionKey为空");
            sendAppErrorMsg("6001", "functionKey");
            return null;
        }

        if (StringUtils.isBlank(merchantOrderId)) {
            log.warn("我要收款时, 传入参数merchantOrderId为空");
            sendAppErrorMsg("6001", "merchantOrderId");
            return null;
        }

        if (null == merchantOrderTime) {
            log.warn("我要收款时, 传入参数merchantOrderTime为空");
            sendAppErrorMsg("6001", "merchantOrderTime");
            return null;
        }

        if (null == transAmt) {
            log.warn("我要收款时, 传入参数transAmt为空");
            sendAppErrorMsg("6001", "transAmt");
            return null;
        }

        if (StringUtils.isBlank(accountNumber)) {
            log.warn("我要收款时, 传入参数accountNumber为空");
            sendAppErrorMsg("6001", "accountNumber");
            return null;
        }
        if (StringUtils.isBlank(pin)) {
            log.warn("我要收款时, 传入参数pin为空");
            sendAppErrorMsg("6001", "pin");
            return null;
        }
        if (StringUtils.isBlank(track2Data)) {
            log.warn("我要收款时, 传入参数track2Data为空");
            sendAppErrorMsg("6001", "track2Data");
            return null;
        }

        //判断日期是否是今天
        Date date = new Date();
        String today = DateConvertUtil.dateString(date, "yyyyMMdd");
        if (!merchantOrderTime.startsWith(today)) {
            merchantOrderId = getMerchantOrderId(date, user.getLoginName());
            merchantOrderTime = DateConvertUtil.dateString(date, "yyyyMMddHHmmss");
        }

        //查出商户订单号 是否存在
        TransOrder transOrder = transOrderService.searchOrderByMerchantOrderId(user.getLoginName(), merchantOrderId);
        if (null != transOrder) {
            sendAppErrorMsg("6101", merchantOrderId);
            return null;
        }

        if ("1".equals(encryType)) {
            track2Data = ME30DataDecode.decryptTrace2(track2Data);
        } else if ("2".equals(encryType)) {
            String trackOData = getJsonString("trackOData");
            String[] trackA = ME30DataDecode.decryptTrace2_aic(trackOData, track2Data);
            track2Data = trackA[0];
            track3Data = trackA[1];
        }
        track2Data = track2Data.replaceAll("F", "");//屏蔽二磁道有F的情况

        //组装 发送数据
        Qian4SendLog send = new Qian4SendLog();
        send.setCollectionType(user.getChannelId().intValue());
        send.setRoleId(roleId);
        send.setCallType(0);
        send.setUserId(userId);
        send.setOrderTypeId(1l);
        send.setApplication("Purchase.Req");
        send.setTransType("100001");//
        send.setSendTime(date);
        send.setSendSeqId(TimeUtils.getTimeToString());
        send.setTerminalId(terminalId);
        send.setPlatformId("1");
        send.setRoleId(roleId);
        send.setMerchantOrderId(merchantOrderId);//商户订单号
        send.setMerchantOrderTime(DateConvertUtil.stringDate(merchantOrderTime, "yyyyMMddHHmmss"));//商户订单号时间
        send.setTransTime(send.getSendTime());
        send.setTransAmt(transAmt);
        send.setCurrency("156");
        send.setAccountNumber(accountNumber);
        send.setPin(pin);
        send.setTrack2Data(track2Data);
        send.setTrack3Data(track3Data);
        send.setDynamicKeyData(dynamicKeyData);
        send.setMerchantSign(merchantSign);
        send.setSenderSign(senderSign);
        send.setServiceInfo(serviceInfo);
        send.setTerminalInfo(terminalInfo);
        send.setMac(mac);
        send.setIp(URLDecoderTools.getRemoteHost(getRequest()));//IP
        send.setIcCardYu(icCardYu);
        send.setCardTypeN(StringUtils.isEmpty(icCardYu) ? 1 : 2);//1 磁条卡 2 IC卡
        send.setTransTerminalId(transTerminalId);

        transOrder = new TransOrder();
        transOrder.setOrderNum(orderNum);
        transOrder.setOrderTypeId(1l);//我要收款
        transOrder.setUserId(userId);
        transOrder.setPUserId(user.getPUserId());//父用户Id
        transOrder.setTransMoney(Double.parseDouble(transAmt) / 100.0);
        transOrder.setRootCategory("账务管理");
        transOrder.setCategory("秒到收款");
        transOrder.setBankCard(accountNumber);
        transOrder.setObjectiveName(StringUtils.isBlank(user.getCardholder()) ? user.getUserName() : user.getCardholder());//user.getUserName());//对方持卡人姓名
        transOrder.setObjectiveCard(user.getBankCard());//对方银行卡
        transOrder.setObjectiveOpBank(user.getOpeningBank());//对方银行
        transOrder.setStatus(3);//交易状态  0交易失败 1交易成功 2银行交易处理中 3 未付款 4等待对方付款5关闭交易
        transOrder.setClearing(0);//结算状态 0未结算 1结算
        transOrder.setCreateDate(date);
        transOrder.setUpdateLongTime(date.getTime());
        transOrder.setObjectiveBBank(user.getBranchesBank());//对方。银行支行
        transOrder.setObjectiveBBProvince(user.getBBankProvince());
        transOrder.setObjectiveBBCity(user.getBBankCity());
        transOrder.setObjectiveMobile(user.getMobile());//对方手机号
        transOrder.setObjectiveBBankCode(user.getBranchesBankCode());//支行Code
        transOrder.setTerminalTypeId(terminalTypeId);
        transOrder.setRoleId(roleId);
        transOrder.setSignaturePath(signaturePath);
        transOrder.setCardTypeN(send.getCardTypeN());//1 磁条卡 2 IC卡
        transOrder.setClientType(clientType);
        transOrder.setMachineType(user.getMachineType());//刷卡器类型
        String mainValue = settingsService.getMainValueByFk(functionKey);
        double feeRate = mainValue == null ? 0.0 : Double.parseDouble(mainValue);
        transOrder.setFeeRate(feeRate);
        transOrder.setFeeRate(feeRate);//用户费率
        double fee = NumberUtil.roundF2(feeRate * transOrder.getTransMoney());
        transOrder.setFeeMoney(fee);
        transOrder.setChargeAmount(transOrder.getTransMoney() - fee);
        transOrder.setFdMaxFee(user.getFdMaxFee());//用户封顶最高
        transOrder.setFdMinFee(user.getFdMinFee());//用户封顶最低
        transOrder.setTransTerminalId(transTerminalId);

        Object[] resultA = new Object[2];
        resultA[0] = send;
        resultA[1] = transOrder;
        return resultA;
    }

    /**
     * 生产 商户订单号
     *
     * @param mobile
     * @return
     */
    protected String getMerchantOrderId(Date date, String mobile) {
        String end = "";
        if (StringUtils.isNotBlank(mobile)) {
            end = mobile.substring(mobile.length() - 6);
        }
        StringBuilder sb = new StringBuilder();
        String orderId = DateConvertUtil.dateString(date, "yyyyMMddHHmmssSSS");
        return sb.append(orderId).append(end).toString();
    }

    /**
     * 判断降级交易是否需要切换通道
     *
     * @param channelId
     * @return
     */
    private int whetherChangeChannel(String channelId, Qian4SendLog send) throws SQLException {
        if (!checkIcInfo(send) && isFhCard(send.getTrack2Data())) {
            //如果是降级交易,进行判断是否需要切换通道,需要切换通道时,从数据库获取切换到那个通道
            Settings settings = null;
            String mainValue = null;
            String value2 = null;
            if (null != settingsService.getSettingsByFk("WHETHER_CHANGE_CHANNEL")) {
                settings = settingsService.getSettingsByFk("WHETHER_CHANGE_CHANNEL");
                mainValue = settings.getMainValue().trim();
                value2 = settings.getValue2().trim();
                if (StringUtils.isNotBlank(mainValue)) {
                    if (mainValue.contains(channelId) && StringUtils.isNotBlank(value2) && !("0".equals(value2))) {
                        channelId = value2;
                    }
                }
            }
        }
        return Integer.valueOf(channelId);
    }

    /**
     * 计算手续费
     *
     * @param user
     * @param roleId
     * @param transMoney
     * @param feeRate
     * @return
     */
    private Double calculateFee(User user, Long roleId, Double transMoney, Double feeRate) {
        double fee = NumberUtil.roundF2(feeRate * transMoney);
        if (3 == roleId.intValue()) {//封顶版
            if (fee > user.getFdMaxFee()) {
                fee = user.getFdMaxFee();
            } else if (fee < user.getFdMinFee()) {
                fee = user.getFdMinFee();
            }
        } else if (4 == roleId.intValue()) {
            fee = 0.0;
        }
        return fee;
    }

    /**
     * 判定是否为复合卡（二磁道d后面YYMMa 第五位 a = 2 或 a = 6 证明是复合卡）
     *
     * @param track2Data
     * @return
     */
    private boolean isFhCard(String track2Data) {
        track2Data = track2Data.toLowerCase();
        String data = track2Data.split("d")[1];
        int fv = Integer.valueOf(data.substring(4, 5));
        if (fv == 2 || fv == 6) {
            return true;
        } else {
            return false;
        }
    }

    private Boolean checkIcInfo(Qian4SendLog sendLog) {
        ICCardParam icCardParam;
        if (sendLog != null && sendLog.getIccParam() != null)
            icCardParam = sendLog.getIccParam();
        else return false;
        return StringUtils.isNotEmpty(icCardParam.getBit55());
    }

    /**
     * 从数据库中获取配置
     * @param functionKey
     * @return
     * @throws SQLException
     */
    public double getConfig(String functionKey) throws SQLException{
        double result = 0.0;
        String mainValue = null;
        if (null != settingsService.getSettingsByFk(functionKey)) {
            mainValue = settingsService.getMainValueByFk(functionKey);
            result = Double.parseDouble(mainValue);
        }
        return result;
    }

    /**
     * 返回
     *
     * @param pr
     * @param transOrder
     * @param transPriorSettle
     * @param user
     * @param tc
     * @return
     * @throws Exception
     */
    protected Map<String, Object> purchaseResolveResult(Qian4SendLog send, PurchaseResult pr, TransOrder transOrder, TransPriorSettle transPriorSettle, User user, Tchannel tc) throws Exception {
        Map<String, Object> result = new HashMap<String, Object>();
        CardCer cardCer = new CardCer();
        cardCer.setOrderNum(transOrder.getOrderNum());
        cardCer = cardCerService.searchEntity(cardCer);
        UserNocardpayLog ncpl = new UserNocardpayLog();
        ncpl.setOrderid(transOrder.getOrderNum());
        ncpl.setUserid(user.getId());
        ncpl.setCardnumber(transOrder.getBankCard());
        ncpl.setCardholder(user.getCardholder());
        ncpl.setIdcard(user.getIdentityCard());
        ncpl.setPhonenumber(user.getMobile());
        ncpl.setIssuBank(user.getOpeningBank());
        ncpl.setTransamount(new BigDecimal(transOrder.getTransMoney()));
        ncpl.setTranstime(transOrder.getCreateDate());
        ncpl.setBankcardtype(transOrder.getCardTypeN());
        ncpl.setStatus(String.valueOf(pr.getStatus()));
        if (0 == pr.getStatus()) {//错误
            log.debug("秒到收款失败");
            result.put("bankResp", "0");
            result.put("reqCode", pr.getReqCode());
            result.put("reqMsg", pr.getReqMsg());
            accountManageQ4Service.receivablesError(transPriorSettle, pr.getReqCode(), pr.getReqMsg());
            qian4SendLogService.updateResCodeMassage(transPriorSettle.getSendId(), pr.getReqCode(), pr.getReqMsg());
            cardCer.setStatus(0);
            ncpl.setErrorcode(pr.getReqCode());
            ncpl.setErrormsg(pr.getReqMsg());
        } else {
            transPriorSettle = accountManageQ4Service.purchaseResolveResult(transPriorSettle, send, pr, tc, user.getOrganizationId());
            String cParam = terminalTypeId + "_" + transPriorSettle.getId();
            String cParamB64 = new String(Des3.encodeXP(cParam));

            result.put("bankResp", "1");
            result.put("category", transOrder.getCategory());
            result.put("status", transOrder.getStatus());
            result.put("orderNum", transOrder.getOrderNum());
            result.put("transTime", DateConvertUtil.dateString(transOrder.getCreateDate(), "HH:mm:ss"));
            result.put("certificateUrl", Certificate + cParamB64);

            String acquirersName = user.getOpeningBank();
            if (null != acquirersName) {
                acquirersName = acquirersName.replace("中国", "");
            }
            result.put("merchantName", MERCHANT_NAME);//商户名称
            result.put("merchantId", MERCHANT_ID);//商户编号
            result.put("terminalId", transPriorSettle.getTerminalId());//终端编号
            result.put("acquirersName", null != acquirersName ? acquirersName : transPriorSettle.getAcquirersName());//收单行
            result.put("issueBank", null == transPriorSettle.getIssueBank() ? "" : transPriorSettle.getIssueBank());//发卡行
            result.put("bankCard", transOrder.getBankCard());//收款卡号
            result.put("cardType", null == transPriorSettle.getCardType() ? "" : transPriorSettle.getCardType());//收款卡号
            result.put("expireDate", null == transPriorSettle.getExpireDate() ? "" : transPriorSettle.getExpireDate());//卡有效期（预授权时）
            result.put("batchId", null == transPriorSettle.getBatchId() ? "" : transPriorSettle.getBatchId());//批次号
            result.put("authorizationCode", null == transPriorSettle.getAuthorizationCode() ? "" : transPriorSettle.getAuthorizationCode());//授权码
            result.put("bankTransTime", DateConvertUtil.dateString(transOrder.getCreateDate(), "yyyy/MM/dd"));//日期/时间  transPriorSettle.getBankTransTime()
            result.put("transMoney", transOrder.getTransMoney());//交易金额
            result.put("bankRef", transPriorSettle.getBankRef());//参考号
            result.put("searchId", transPriorSettle.getSearchId());//凭证号
            result.put("transId", transPriorSettle.getBankOrderNum());//凭证号
            result.put("receivablesId", transPriorSettle.getId());//凭证号

            result.put("reqCode", transPriorSettle.getResponseCode());
            if (StringUtils.isNotBlank(transPriorSettle.getBankMessage()))
                result.put("reqMsg", transPriorSettle.getBankMessage());

            result.put("merchantOrderId", transPriorSettle.getMerchantOrderId());
            cardCer.setStatus(2);
            SSBindCards ssBindCards = new SSBindCards();
            ssBindCards.setStatus(2);
            ssBindCards.setCardHolder(user.getCardholder());
            ssBindCards.setCardNumber(transOrder.getBankCard());
            ssBindCards.setLoginName(user.getLoginName());
            ssBindCards.setIssueBank(transPriorSettle.getIssueBank());
            ssBindCards.setPhoneNumber(user.getMobile());
            ssBindCards.setUserId(user.getId());
            ssBindCardsService.insertSSBindCards(ssBindCards);
        }
        cardCerService.updateEntity(cardCer);
        ssBindCardsService.insertUserNocardpayLog(ncpl);
        return result;
    }

}
